<?php
/**
 * Created by PhpStorm.
 * User: rubekid
 * Date: 2016/10/29
 * Time: 12:34
 */

namespace SmartWiki\Http\Controllers;

use Faker\Provider\Uuid;
use Illuminate\Filesystem\Filesystem;
use League\Flysystem\Exception;
use PclZip;
use SmartWiki\Models\Axure;
use SmartWiki\Models\Project;


class AxureController extends Controller
{


    /**
     * 原型编辑首页
     * @param $project_id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function index($project_id)
    {
        if(empty($project_id) or $project_id <= 0){
            abort(404);
        }
        $project = Project::find($project_id);
        if(empty($project)){
            abort(404);
        }
        //判断是否有编辑权限
        if(Project::hasProjectEdit($project_id,$this->member->member_id) === false){
            abort(403);
        }

        $jsonArray = Axure::getAxures($project_id);
        $this->data['project_id'] = $project_id;
        $this->data['project'] = $project;
        $this->data['lists'] = $jsonArray;
        $this->data['member_projects'] = true;
        $this->data['is_owner'] = Project::isOwner($project_id,$this->member->member_id) ;

        return view('axure.axure',$this->data);
    }

    /**
     * 文件上传
     * @return \Illuminate\Http\JsonResponse
     */
    public function save()
    {
        $id = $this->request->input("id");
        $projectId = $this->request->input("project_id");
        $name = $this->request->input("name");
        $remote = $this->request->input("remote");
        $url = $this->request->input("url");
        $isNew = empty($id);
        if(!$isNew) {
            //查看是否有重名原型
            $item = Axure::where('project_id', '=', $projectId)->where('axure_name', '=', $name)->where('axure_id','<>',$id)->first(['axure_id']);

            if (empty($item) === false) {
                return $this->jsonResult(70005);
            }
        }else{
            //查看是否有重名原型
            $item = Axure::where('project_id', '=', $projectId)->where('axure_name', '=', $name)->first(['axure_id']);
            if (empty($item) === false) {
                return $this->jsonResult(70005);
            }
        }

        $axure = new Axure();

        if(!$isNew){
            $axure = Axure::find($id);
            if($axure == null){
                $data['success'] = 0;
                $data['message'] = '操作的原型不存在或已删除';
                return $this->response->json($data);
            }
        }
        else{
            $axure->create_time = date('Y-m-d H:i:s');
            $axure->create_at = $this->member_id;
            $axure->axure_id = Uuid::uuid();
        }
        $axure->modify_time = date('Y-m-d H:i:s');
        $axure->modify_at = $this->member_id;
        $axure->project_id = $projectId;
        $axure->axure_name = $name;
        $axure->remote = $remote;

        if($axure->remote == 1){
            $axure->axure_url = $url;
        }

        $allowExt = ["zip", "rar"];
        //如果上传文件
        if(isset($_FILES['file']) && $axure->remote == 0){
            $file = $this->request->file('file');
        }

        $dirPath = public_path('axure/' . $projectId);
        //如果目标目录不能创建
        if (!is_dir($dirPath) && !mkdir($dirPath)) {
            $data['success'] = 0;
            $data['message'] = '上传目录没有创建文件夹权限';
            return $this->response->json($data);
        }
        //如果目标目录没有写入权限
        if(is_dir($dirPath) && !is_writable($dirPath)) {
            $data['success'] = 0;
            $data['message'] = '上传目录没有写入权限';
            return $this->response->json($data);
        }



        //校验文件
        if(isset($file) && $file->isValid()){
            $ext = $file -> getClientOriginalExtension(); //上传文件的后缀
            //判断文件类型
            if(empty($ext) or in_array(strtolower($ext),$allowExt) === false){
                $data['success'] = 0;
                $data['message'] = '不允许的文件类型';

                return $this->response->json($data);
            }

            //生成文件名
            $fileName = $axure->axure_id .'.'.$ext;
            try{
                $path = $file->move('axure/' . $projectId, $fileName);
                $archivePath  = $dirPath . "/" . $fileName;
                $dest = $dirPath . "/" . $axure->axure_id;

                if(is_dir($dest)){
                    //删除旧数据
                    $fs = new  Filesystem();
                    $fs->deleteDirectory($dest);
                }

                try{
                    if($ext == "rar"){
                        $this->unrar($archivePath, $dest);
                    }
                    else{
                        $this->unzip($archivePath, $dest);
                    }
                    $this->removeWrapDir($dest);

                }
                catch(Exception $ex){
                    unlink($archivePath);
                    $data['success'] = 0;
                    $data['message'] = '压缩包解压失败';

                    return $this->response->json($data);
                }

                $axure->axure_url = url( '/' . $path->getPath() . '/' . $axure->axure_id );

            }catch (Exception $ex){
                $data['success'] = 0;
                $data['message'] = $ex->getMessage();
                return $this->response->json($data);
            }

        }

        $axure->addOrUpdate();

        $data['success'] = 1;
        $data['message'] = 'ok';
        $data['url'] = url($axure->url);

        //消息通知
        $project = Project::find($projectId);
        if(!empty($project) && !empty($project->webhook)){
            $title = "原型变更通知";
            $desc = $this->member->nickname . ($isNew ? "新增原型":"更新了原型") . "《" .$axure->axure_name . "》";
            $link = $axure->axure_url;
            $msgtype = "link";
            $picUrl = $this->member->headimgurl;
            if(strpos($picUrl, "/") == 0){
                $picUrl = url($picUrl);
            }
            dtalk_notify($project->webhook, $title, $desc, $link, $msgtype, $picUrl);
        }
        return $this->response->json($data);
    }

    /**
     * 删除原型
     * @param int $axure_id
     * @return \Illuminate\Http\JsonResponse
     */
    public function delete($axure_id)
    {
        $axure = Axure::find($axure_id);
        //如果原型不存在
        if(empty($axure)){
            return $this->jsonResult(70001);
        }
        //判断是否有编辑权限
        if(Project::hasProjectEdit($axure->project_id, $this->member_id) == false){
            return $this->jsonResult(70006);
        }
        try{
            $dirPath = public_path('axure/' . $axure->project_id . "/" . $axure->axure_id);
            $fs = new  Filesystem();
            $fs->deleteDirectory($dirPath);
            Axure::deleteAxure($axure_id);
            return $this->jsonResult(0);
        }catch (\Exception $ex){
            if($ex->getCode() == 500){
                Log::error($ex->getMessage(),['trace'=>$ex->getTrace(),'file'=>$ex->getFile(),'line'=>$ex->getLine()]);
                return $this->jsonResult(500,null,'删除失败');
            }else{
                return $this->jsonResult($ex->getCode());
            }
        }
    }

    /**
     * @param $archivePath zip文件路径
     * @param $dest  解压目标目录
     */
    private function unzip($archivePath, $dest){
        $zip = new PclZip($archivePath);
        $zip->extract(PCLZIP_OPT_PATH, $dest);
        unlink($archivePath);
    }

    /**
     * rar解压
     * @param $archivePath
     * @param $dest
     */
    private function unrar($archivePath, $dest){
        $rar_file = rar_open($archivePath) or die("Can't open Rar archive");
        /*example.rar换成其他档桉即可*/
        $entries = rar_list($rar_file);
        foreach ($entries as $entry) {
            $entry->extract($dest);
        }
        rar_close($rar_file);
        unlink($archivePath);
    }

    /**
     * 去掉外层目录
     * @param $dest
     */
    private function removeWrapDir($dest){
        $dir = dir($dest);
        $count = 0;
        $subDest = "";
        while($file = $dir->read())
        {
            if($file=="." || $file == ".."){
                continue;
            }
            $subDest = "$dest/$file";
            $count ++;
            if($count > 1){
                break;
            }
        }

        if($count == 1){
            $tempdir = $dest . time();
            rename($subDest, $tempdir);
            rename($tempdir, $dest);
        }
        $dir->close();
    }

    /**
     * 文件编码
     * @param $file
     * @return mixed|null
     */
    function detect_encoding($file) {
        $list = array('GBK', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'ISO-8859-1');
        $str = file_get_contents($file);
        foreach ($list as $item) {
            $tmp = mb_convert_encoding($str, $item, $item);
            if (md5($tmp) == md5($str)) {
                return $item;
            }
        }
        return null;
    }
}